/* ------------------------------------------------------------------------*
 *
 * ------------------------------------------------------------------------*/
#include "sys_ext.h"
#include "swspi.h"
#include "nor_cmd.h"
#include "board.h"

uint8_t gd25_id[8];
extern const spi_flash_hal_type flash_hal;

static gpio_init_cfg_type gpio_cfg[] = 
{
    {GPIOB, GPIO_Mode_OUT_PP, GPIO_MaxSpeed_50MHz, 0, GPIO_Pins_1},  //CLK
    {GPIOB, GPIO_Mode_OUT_PP, GPIO_MaxSpeed_50MHz, 0, GPIO_Pins_10}, //MOSI
    {GPIOB, GPIO_Mode_IN_PU, GPIO_MaxSpeed_50MHz, 0, GPIO_Pins_11},  //MISO
    {GPIOB, GPIO_Mode_OUT_PP, GPIO_MaxSpeed_50MHz, 0, GPIO_Pins_7},  //WP
    {GPIOB, GPIO_Mode_OUT_PP, GPIO_MaxSpeed_50MHz, 0, GPIO_Pins_6},  //HOLD
    {GPIOA, GPIO_Mode_OUT_PP, GPIO_MaxSpeed_50MHz, 0, GPIO_Pins_8},  //CS
};

#define cs        PAout(8)
#define sck       PBout(1)
#define mosi      PBout(10)
#define miso      PBin(11)

static void cs_out_high(void)
{
	cs = 1;
}

static void cs_out_low(void)
{
	cs = 0;
}

static void sck_out_high(void)
{
	sck = 1;
}

static void sck_out_low(void)
{
	sck = 0;
}

static void mosi_out_high(void)
{
	mosi = 1;
}
static void mosi_out_low(void)
{
	mosi = 0;
}

static uint8_t miso_st_get(void)
{
    __DSB();
	return miso;
}

static void insert_clks(void)
{
	__DSB();
}

static spi_cfg_type spi_cfg =
{
	.cs_out_high = cs_out_high,
	.cs_out_low = cs_out_low,
	.sck_out_high = sck_out_high,
	.sck_out_low = sck_out_low,
	.mosi_out_high = mosi_out_high,
	.mosi_out_low = mosi_out_low,
	.miso_st_get = miso_st_get,
};

void spim_sw_spi_init(void)
{
    int index;
    GPIO_InitType GPIO_InitStructure;
    
    for(index=0; index < sizeof(gpio_cfg)/sizeof(gpio_init_cfg_type);index++)
    {
        GPIO_InitStructure.GPIO_Mode = gpio_cfg[index].mode;
        GPIO_InitStructure.GPIO_MaxSpeed = gpio_cfg[index].speed;
        GPIO_InitStructure.GPIO_Pins = gpio_cfg[index].pin;
        GPIO_Init(gpio_cfg[index].port, &GPIO_InitStructure);
        
        if((gpio_cfg[index].mode == GPIO_Mode_OUT_OD) || (gpio_cfg[index].mode == GPIO_Mode_OUT_PP))
        {
            if(gpio_cfg[index].val_init)
            {
                GPIO_SetBits(gpio_cfg[index].port, gpio_cfg[index].pin);
            }
            else
            {
                GPIO_ResetBits(gpio_cfg[index].port, gpio_cfg[index].pin);
            }
        }
    }
    
    PBout(7) = 1;
    PBout(6) = 1;
	nor_init(&flash_hal, 1);
}

void gd25_cs(uint8_t st)
{
    sw_spi_cs(&spi_cfg, st);
}

void gd25_spi_mode(void)
{
    
}

void gd25_spi_wb(uint8_t dataW)
{
    sw_spi8_rw(&spi_cfg, dataW);
}

uint8_t gd25_spi_rb(void)
{
	return sw_spi8_rw(&spi_cfg, 0x00);
}

uint8_t gd25_spi_cmd_send(uint8_t *dataw, uint8_t Len)
{
    while(Len--)
    {
        sw_spi8_rw(&spi_cfg, *dataw++);
    }
	return 0;
}

uint8_t gd25_spi_write(const uint8_t *dataw, uint32_t Len)
{
    while(Len--)
    {
        sw_spi8_rw(&spi_cfg, *dataw++);
    }
	return 0;
}

uint8_t gd25_spi_read(uint8_t *datar, uint32_t Len)
{
    while(Len--)
    {
        *datar = sw_spi8_rw(&spi_cfg, 0);
        datar++;
    }
	return 0;
}

uint8_t gd25_qpi_write(uint8_t *dataw, uint32_t Len)
{
    __DSB();
	return 0;
}

uint8_t gd25_qpi_read(uint8_t *datar, uint32_t Len)
{
    __DSB();
	return 0;
}

const spi_flash_hal_type flash_hal = 
{
	gd25_cs,
		gd25_spi_mode,
		gd25_spi_mode,
		gd25_spi_mode,
		gd25_spi_rb,
		gd25_spi_wb,
		gd25_spi_write,
		gd25_spi_read,
		0,
		0
};
